import datetime
from typing import Optional

import sqlalchemy as sa
from sqlalchemy import ForeignKey, func
from sqlalchemy.orm import Mapped, mapped_column, relationship

from src.application.order.enums import OrderPeriod, OrderStatus, OrderType
from src.infrastructure.db.models.base import Base
from src.infrastructure.db.models.m2ms import allowed_ips_orders, orders_proxies


class Order(Base):
    __tablename__ = "order"
    __mapper_args__ = {"eager_defaults": True}

    id: Mapped[int] = mapped_column(primary_key=True)
    status: Mapped[OrderStatus] = mapped_column(server_default="active")
    type: Mapped[OrderType] = mapped_column(server_default="proxy")
    summ: Mapped[float] = mapped_column(nullable=False)
    summ_total: Mapped[float] = mapped_column(nullable=False)
    period: Mapped[OrderPeriod] = mapped_column(nullable=False)
    proxies = relationship("Proxy", secondary=orders_proxies, back_populates="orders")
    user = relationship("User", back_populates="orders")
    user_id: Mapped[int] = mapped_column(ForeignKey("user.id"))
    allowed_ips = relationship("AllowedIP", secondary=allowed_ips_orders, back_populates="orders")
    category = relationship("Category", back_populates="orders")
    category_id: Mapped[int] = mapped_column(ForeignKey("category.id"))
    site = relationship("Site", back_populates="orders")
    site_id: Mapped[int] = mapped_column(ForeignKey("site.id"))
    country = relationship("Country", back_populates="orders")
    country_id: Mapped[int] = mapped_column(ForeignKey("country.id"))
    provider = relationship("ProxyProvider", back_populates="orders")
    provider_id: Mapped[int] = mapped_column(ForeignKey("provider.id"))
    vpn_server = relationship("VPNServer", back_populates="orders")
    vpn_server_id: Mapped[int] = mapped_column(ForeignKey("vpn_server.id"))
    auto_renew: Mapped[bool] = mapped_column(server_default=sa.False_())
    expiring_on: Mapped[Optional[datetime.datetime]]
    was_renewed: Mapped[Optional[datetime.datetime]]
    last_notified: Mapped[Optional[datetime.datetime]]
    was_created: Mapped[datetime.datetime] = mapped_column(server_default=func.now())

    def __repr__(self):
        if self.type == OrderType.subscription:
            return f"<Subscription №{self.id} {self.summ}$ {self.was_created}>"
        elif self.type == OrderType.vpn:
            return f"<VPN №{self.id} {self.summ}$ {self.was_created}>"
        elif self.type == OrderType.vpn_router:
            return f"<VPN Router №{self.id} {self.summ}$ {self.was_created}>"
        return f"<Order №{self.id} {self.summ}$ {self.was_created}>"

    def __str__(self):
        return self.__repr__()
